package generator;

import java.util.List;
import java.util.regex.Pattern;

public class Director {
	private SourceBuilder mBuilder;

	public Director(SourceBuilder builder) {
		mBuilder = builder;
	}

	public void setData(String clazz, String description, List<String[]> dataList) {

		checkClassName(clazz);

		String pkg;
		String name;
		int dotPos = clazz.lastIndexOf(".");
		if (dotPos == -1) {
			pkg = "";
			name = clazz;
		} else {
			pkg = clazz.substring(0, dotPos);
			name = clazz.substring(dotPos + 1);
		}
		mBuilder.setClass(pkg, name, description);

		for (String[] data : dataList) {

			String visiblity = null;
			String type = null;
			String field = null;
			String fieldDesc = null;
			if (data.length == 6) {
				visiblity = data[2].trim();
				type = data[3].trim();
				field = data[4].trim();
				fieldDesc = data[5].trim();
			} else {
				visiblity = data[2].trim();
				type = data[3].trim() + ", " + data[4].trim();
				field = data[5].trim();
				fieldDesc = data[6].trim();
			}

			checkVisiblity(visiblity);
			checkFieldType(type);
			checkFieldName(field);

			mBuilder.addMember(visiblity, type, field, fieldDesc);
		}
	}

	private void checkClassName(String name) {
		System.out.println("checkClassName()" + name);
		if (!Pattern.matches("(([a-zA-Z_][a-zA-Z_0-9]*)([.]?))*", name)) {
			throw new IllegalArgumentException("Invalid class name:" + name);
		}
	}

	private void checkVisiblity(String visiblity) {
		if (!"public".equals(visiblity)
				&& !"private".equals(visiblity)
				&& !"protected".equals(visiblity)
				&& !"".equals(visiblity)) {
			throw new IllegalArgumentException("Invalid visiblity:" + visiblity);
		}
	}

	private void checkFieldType(String type) {
		// String, ArrayList<String>, HashMap<String, Integer>
		// ([a-zA-Z_][a-zA-Z_0-9]*)
		// |([a-zA-Z_][a-zA-Z_0-9]*)<([a-zA-Z_][a-zA-Z_0-9]*)>
		// |([a-zA-Z_][a-zA-Z_0-9]*)<([a-zA-Z_][a-zA-Z_0-9]*),\\s([a-zA-Z_][a-zA-Z_0-9]*)>
		if (!Pattern.matches("([a-zA-Z_][a-zA-Z_0-9]*)" +
				"|([a-zA-Z_][a-zA-Z_0-9]*\\[\\])" +
				"|([a-zA-Z_][a-zA-Z_0-9]*)<([a-zA-Z_][a-zA-Z_0-9]*)>" +
				"|([a-zA-Z_][a-zA-Z_0-9]*)<([a-zA-Z_][a-zA-Z_0-9]*),\\s([a-zA-Z_][a-zA-Z_0-9]*)>", type)) {
			throw new IllegalArgumentException("Invalid field type:" + type);
		}
	}

	private void checkFieldName(String field) {
		if (!Pattern.matches("(([a-zA-Z_][a-zA-Z_0-9]*))*", field)) {
			throw new IllegalArgumentException("Invalid field name:" + field);
		}
	}

	public String create() {
		return mBuilder.build();
	}
}
